package com.polytech.diploma.OracleStat;

import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.pentaho.di.core.database.Database;

import com.polytech.diploma.OracleStat.Parsers.FingerPrintsParser;
import com.polytech.diploma.OracleStat.Parsers.FromClauseParser;
import com.polytech.diploma.StatAccumulator.DatePrecision;
import com.polytech.diploma.StatAccumulator.ModificationNumAccumulator;
import com.polytech.diploma.StatAccumulator.OracleStatAccumulator;
import com.polytech.diploma.StatAccumulator.StatPercentage;

public class OracleQueryProcessor {

	protected OracleTablesStat tablesStat = null;
	protected Set<SQLStatData> selectData = null;
	protected OracleStatAccumulator statAccumulator = null;
	StatPercentage statPercentage = null;
		
	public OracleQueryProcessor(String schemaName, 
				Database DBConnection, StatPercentage statPercentage) 
	{
		tablesStat = OracleTablesStat.getInstance(schemaName, DBConnection);
		selectData = new HashSet<SQLStatData>();
		statAccumulator = OracleStatAccumulator.getInstance();
		this.statPercentage = statPercentage;
	}
	
	/*
	 * TODO: Change return type
	 */
	
	public Set<SQLStatData> processQueries()
	{
		/**
		 * Calculate Update frequency
		 */
		Date maxDate = null;
		Date minDate = null;		
		
		for(SQLStatData statData : selectData)
		{
			if(maxDate==null && minDate == null)
			{
				maxDate = statData.getFirstLoadTime();
				minDate = statData.getFirstLoadTime();
				continue;
			}
			
			if(statData.getFirstLoadTime().before(minDate))
				minDate = statData.getFirstLoadTime();
			
			if(statData.getFirstLoadTime().after(maxDate))
				maxDate = statData.getFirstLoadTime();
		}
		
		for(SQLStatData statData : selectData)
		{
			for(String tableName : statData.getTableNames())
			{
				statData.addUpdateNum(tablesStat.getTableStat(tableName));
			}
			
			int timeInterval = ModificationNumAccumulator.calculateTimeInterval(
					DatePrecision.MINUTES, minDate, maxDate);
			
			if (timeInterval == 0)
				timeInterval = 1;
			
			double frequency = (double)statData.getUpdateNum()/timeInterval;
			
			statData.setUpdateFrequency(frequency);
		}
		
		return statAccumulator.doStatAccumulation(selectData, statPercentage);
	}
	
	public void addQuery(SQLStatData statData)
	{
		if(statData.getCommandType() == CommandType.SELECT)
		{
			statData=FingerPrintsParser.doParse(statData);
			statData.addTableNames(FromClauseParser
										.parseSelectFromClause(statData.getSqlText()));
			selectData.add(statData);
		}
		else
		{
			List<String> tableNames = FromClauseParser
											.parseFromClause(statData.getSqlText(),
																statData.getCommandType());
			for(String tableName : tableNames)
			{
				tablesStat.addTable(tableName, statData.getCommandType());
			}
		}
	}
}
